import { useState, useRef } from 'react';

import { commonRecognizeApi, commonUploadApi } from '@/api/common';

export interface PlayInfo {
	localPlay: boolean;
	recordPlay: boolean;
}

export const useAudioRecorder = () => {
	const [playInfo, setPlayInfo] = useState<PlayInfo>({
		localPlay: false,
		recordPlay: false
	});
	const [recordList, setRecordList] = useState<any[]>([]);
	const [fileList, setFileList] = useState<File[]>([]);
	const [isRecording, setIsRecording] = useState(false);
	const [stopRecording, setStopRecording] = useState<() => void>(() => {});
	const [error, setError] = useState<string | null>(null);
	const [recordFile, setRecordFile] = useState<File | null>(null);
	const fileInputRef = useRef<HTMLInputElement>(null);

	// 上传本地文件
	const uploadLocalFile = async (
		audioFile: File,
		isEnd = false,
		onSuccess?: (result: string) => void
	) => {
		const formData = new FormData();
		formData.append('file', audioFile);

		const response = await commonUploadApi(formData);

		if (!response.success) {
			throw new Error('上传失败');
		}

		const info = await commonRecognizeApi({
			fileUrl: response.data
		});

		console.log('识别结果:', info);
		const newInfoList = '';
		if (info.success && onSuccess) {
			onSuccess(info.data as string);
		}

		const newList = [...recordList, response.data];
		setRecordList(newList);

		return { response, info, isEnd };
	};

	// 发送音频到服务器
	const sendAudioToServer = async (
		audioBlob: Blob,
		isEnd = false,
		onSuccess?: (result: string) => void
	) => {
		try {
			const audioFile = new File([audioBlob], 'audio.wav', { type: 'audio/wav' });
			const response = uploadLocalFile(audioFile, isEnd, onSuccess);
			return response;
		} catch (error) {
			console.error('上传音频失败:', error);
			setError('音频上传失败，请重试');
			setTimeout(() => setError(null), 5000);
			throw error;
		}
	};

	// 开始录音
	const handleRecordVoice = async (onSuccess?: (result: string) => void) => {
		try {
			if (isRecording) {
				console.warn('录音已在进行中');
				return;
			}

			setError(null);
			const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
			const mediaRecorder = new MediaRecorder(stream);
			const allChunks: Blob[] = [];
			let intervalTimer: NodeJS.Timeout | null = null;

			if (stopRecording) {
				stopRecording();
			}

			mediaRecorder.ondataavailable = event => {
				allChunks.push(event.data);
			};

			mediaRecorder.onstop = async () => {
				// 清除定时器
				if (intervalTimer) {
					clearInterval(intervalTimer);
					intervalTimer = null;
				}
				setIsRecording(false);

				try {
					if (allChunks.length > 0) {
						const audioBlob = new Blob(allChunks, { type: 'audio/wav' });
						await sendAudioToServer(audioBlob, true, onSuccess);
					}
				} catch (error) {
					console.error('录音停止处理错误:', error);
					setError('录音处理失败');
				} finally {
					stream.getTracks().forEach(track => track.stop());
				}
			};

			mediaRecorder.start();

			intervalTimer = setInterval(async () => {
				if (mediaRecorder.state === 'recording') {
					const tempChunks: Blob[] = [];
					mediaRecorder.requestData();

					setTimeout(async () => {
						if (allChunks.length > 0) {
							const newChunks = allChunks.slice(tempChunks.length);
							if (newChunks.length > 0) {
								const audioBlob = new Blob(newChunks, { type: 'audio/wav' });
								await sendAudioToServer(audioBlob, false, onSuccess);
							}
						}
					}, 100);
				}
			}, 10000);

			const stopAndSendAudio = async () => {
				if (mediaRecorder && mediaRecorder.state === 'recording') {
					mediaRecorder.stop();
					stream.getTracks().forEach(track => track.stop());
				}
			};

			const stopRecordingFn = () => {
				// 清除定时器
				if (intervalTimer) {
					clearInterval(intervalTimer);
					intervalTimer = null;
				}

				if (mediaRecorder.state === 'recording') {
					mediaRecorder.stop();
					stopAndSendAudio();
					const allChunksBlob = new Blob(allChunks, { type: 'audio/wav' });
					const audioFile = new File([allChunksBlob], `recording-${Date.now()}.wav`, {
						type: 'audio/wav'
					});
					setRecordFile(audioFile);
				}
			};

			setStopRecording(() => stopRecordingFn);
			setIsRecording(true);
			return stopRecordingFn;
		} catch (error) {
			console.error('录音失败:', error);
			setError('无法访问麦克风，请检查权限设置');
			setIsRecording(false);
			setTimeout(() => setError(null), 5000);
		}
	};

	// 处理文件上传
	const handleFileChange = async (
		e: React.ChangeEvent<HTMLInputElement>,
		onSuccess?: (result: string) => void
	) => {
		const file = e.target.files?.[0];
		if (!file) return;

		const maxSizeMB = 100;
		const maxSizeBytes = maxSizeMB * 1024 * 1024;

		if (file.size > maxSizeBytes) {
			setError(`文件大小不能超过 ${maxSizeMB}MB`);
			return;
		}

		setFileList([file]);
		uploadLocalFile(file, true, onSuccess);
	};

	// 触发文件上传
	const handleUploadVoice = () => {
		if (fileInputRef.current) {
			fileInputRef.current.value = '';
			fileInputRef.current.click();
		}
	};

	// 播放上传的录音
	const handlePlayUploadRecord = (file: File) => {
		if (file) {
			const audioUrl = URL.createObjectURL(file);
			const audioPlayer = document.getElementById('audioPlayer') as HTMLAudioElement;
			audioPlayer.src = audioUrl;
			if (playInfo.localPlay) {
				audioPlayer.pause();
			} else {
				audioPlayer.play();
			}

			setPlayInfo({
				...playInfo,
				localPlay: !playInfo.localPlay
			});
		}
	};

	// 暂停音频
	const pauseVoice = () => {
		const audioPlayer = document.getElementById('audioPlayer') as HTMLAudioElement;
		audioPlayer.pause();
	};

	// 播放录音
	const handlePlayRecord = () => {
		if (recordFile) {
			const audioUrl = URL.createObjectURL(recordFile);
			const audioPlayer = document.getElementById('audioPlayer') as HTMLAudioElement;
			audioPlayer.src = audioUrl;
			if (playInfo.recordPlay) {
				audioPlayer.pause();
			} else {
				audioPlayer.play();
			}
			setPlayInfo({
				...playInfo,
				recordPlay: !playInfo.recordPlay
			});
		}
	};

	// 删除录音
	const handleRemoveRecord = () => {
		setRecordFile(null);
		if (playInfo.recordPlay) {
			pauseVoice();
			setPlayInfo({
				...playInfo,
				recordPlay: false
			});
		}
	};

	return {
		// 状态
		playInfo,
		setPlayInfo,
		recordList,
		setRecordList,
		fileList,
		setFileList,
		isRecording,
		setIsRecording,
		error,
		setError,
		recordFile,
		setRecordFile,
		fileInputRef,
		stopRecording,
		setStopRecording,

		// 方法
		uploadLocalFile,
		sendAudioToServer,
		handleRecordVoice,
		handleFileChange,
		handleUploadVoice,
		handlePlayUploadRecord,
		pauseVoice,
		handlePlayRecord,
		handleRemoveRecord
	};
};
